<?php

declare(strict_types=1);

namespace So\Aspect;

use Hyperf\Di\Annotation\Inject;
use So\Annotation\AdminLog as AdminLogAnnotation;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use So\Library\Auth as AuthLibrary;
use So\Request;
use Hyperf\DbConnection\Db;

/**
 * 切入AdminLog注解实现管理日志
 * @Aspect
 * @author Saopig <1306222220@qq.com>
 */
class AdminLog extends AbstractAspect
{

    /**
     * @var string[]
     */
    public $annotations = [
        AdminLogAnnotation::class,
    ];

    /**
     * @Inject()
     * @var Request
     */
    protected $request;

    /**
     * @Inject()
     * @var AuthLibrary
     */
    protected $auth;

    public function process(ProceedingJoinPoint $proceedingJoinPoint)
    {
        $Annotation = $proceedingJoinPoint->getAnnotationMetadata();
        $AdminLogAnnotation = $Annotation->class[AdminLogAnnotation::class] ?? $Annotation->method[AdminLogAnnotation::class];
        $nolog = $AdminLogAnnotation->nolog;
        if (in_array($this->request->getPath(), $nolog)) {
            return $proceedingJoinPoint->process();
        }
        $path = '/' . $this->request->getPath();
        Db::beginTransaction();
        try {
            $rule = Db::table("auth_rule")->where("path", '=', $path)->first();
            $data = $this->request->filter();
            foreach ($data as $k => &$v) {
                if (in_array($k, ['password', 'pass', 'pay_pass'])) {
                    $v = '******';
                }
                if (in_array($k, ['_'])) {
                    unset($data[$k]);
                }
            }
            $none = ['/index/login' => "登录"];
            Db::table('admin_log')->insert([
                'admin_id' => $this->auth->id ?: 0,
                'username' => $this->auth->username ?: ($path == '/index/login' ? ($data['username'] ?? '') : ''),
                'url' => $path,
                'title' => isset($rule['title']) ? $rule['title'] : (isset($none[$path]) ? $none[$path] : "未知"),
                'content' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
                'ip' => $this->request->ip(),
                'useragent' => $this->request->getHeaderLine('user-agent'),
                'created_at' => time()
            ]);
            Db::commit();
        } catch (\Exception $e) {
            Db::rollBack();
        }
        return $proceedingJoinPoint->process();
    }
}